package src.service;

import java.util.Set;
import src.data.IncomingMessageSRV;
import src.data.MailBoxSRV;
import src.data.OutgoingMessageSRV;
import src.data.PostOfficeSRV;
import src.data.UserSRV;
import src.domain.MailBox;
import src.common.MessageStatus;
import src.domain.OutgoingMessage;
import src.domain.PostOffice;
import src.domain.User;


public class MailServerService {

private static MailServerService instance=null;

	private MailServerService(){}

	public static MailServerService getInstance() {
		if (instance== null)
			instance= new MailServerService();
		return instance;
	}
	
	public  void saveUser(final String name,final String userName, final String country,final String city,final  String address,final String phoneNumber,final boolean active){
		Executor.execute(new  Closure() {
			public Object execute() {
				UserSRV.save(name, userName, country, city, address, phoneNumber, active);
				return null;
			}
		});
		
	}
	
	public void updateUser(final User user) {
		Executor.execute(new Closure() {
			public Object execute() {
				UserSRV.update(user);
				return null;
			}
		});

	}
	
	public void deleteUser(final long idUser){
		Executor.execute(new  Closure() {
			public Object execute() {
		UserSRV.delete(idUser);
		return null;
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<User> getAllUsers(){
		return (Set<User>) Executor.execute(new  Closure() {
			public Object execute() {
		return UserSRV.getAll();
		
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<User> getUsers(final String name){
		return (Set<User>) Executor.execute(new  Closure() {
			public Object execute() {
			return UserSRV.getUsers(name);

			}
		});
	}
	
	public  void savePostOffice(final String name,final   Set<MailBox> mailBoxes,final Set<PostOffice> trustOffices){
		Executor.execute(new  Closure() {
			public Object execute() {
		PostOfficeSRV.save(name,  mailBoxes, trustOffices);
			return null;
			}
		});
		
	}
	
	public void updatePostOffice(final PostOffice postOffice){
		Executor.execute(new  Closure() {
			public Object execute() {	
		PostOfficeSRV.update(postOffice);
		return null;
			}
		});
	}
	
	public void deletePostOffice(final long idPostOffice){
		Executor.execute(new  Closure() {
			public Object execute() {	
		PostOfficeSRV.delete(idPostOffice);
		return null;
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getAllPostOffices(){
		return (Set<PostOffice>) Executor.execute(new Closure() {
			public Object execute() {
		return PostOfficeSRV.getAll();
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getPostOffices(final String name){
		return (Set<PostOffice>) Executor.execute(new  Closure() {
			public Object execute() {
			return PostOfficeSRV.getPostOffices(name);

			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<MailBox> getMailBoxes(final String name){
		return (Set<MailBox>) Executor.execute(new Closure() {
			public Object execute() {
				return MailBoxSRV.getMailBoxes(name);
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getAvailablePostOffices(final PostOffice postOffice) {
		return (Set<PostOffice>) Executor.execute(new  Closure() {
			public Object execute() {
			return PostOfficeSRV.getAvailablePostOffices(postOffice);
			}
		});
	}
	
	public void saveMailBox(final String name,final  String pass, final boolean active,final  User user,final Set<PostOffice> postOffices){
		Executor.execute(new Closure() {
			public Object execute() {
		MailBoxSRV.save(name, pass, active,user,postOffices);
		return null;
			}
		});
	}
	
	public void updateMailBox(final MailBox mailBox){
		Executor.execute(new Closure() {
			public Object execute() {
		MailBoxSRV.update(mailBox);
		return null;
			}
		});
	}
	
	public void deleteMailBox(final long idMailBox){
		Executor.execute(new Closure() {
			public Object execute() {
		MailBoxSRV.delete(idMailBox);
		return null;
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<MailBox> getAllMailBoxes(){
		return (Set<MailBox>) Executor.execute(new Closure() {
			public Object execute() {
				return MailBoxSRV.getAll();
			}
		});
	}
	
	
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getUnassignedPostOffices(final Long idMailBox) {
		return (Set<PostOffice>) Executor.execute(new  Closure() {
			public Object execute() {
			return MailBoxSRV.getUnassignedPostOffices(idMailBox);
			}
		});
	}
	
	public MailBox signIn(final String nameMailBox,final String passMailBox){
		return (MailBox) Executor.execute(new  Closure() {
			public Object execute() {
			return MailBoxSRV.getByNameAndPass(nameMailBox, passMailBox);
			}
		});
	}
	
	public void sendMessage(final OutgoingMessage outgoingMessage) {
		Executor.execute(new Closure() {
			public Object execute() {
				OutgoingMessageSRV.save(outgoingMessage);
				/*for (MailBox mailBox : outgoingMessage.getSender().sendMessage(outgoingMessage))
					MailBoxSRV.update(mailBox);*/
				return null;
			}
		});
	}
	
	public void changeMessageStatus(final long idIncomingMessage,final MessageStatus messageStatus) {
		Executor.execute(new Closure() {
			public Object execute() {
				IncomingMessageSRV.getByID(idIncomingMessage).setMessageStatus(messageStatus);
				return null;
			}
		});

	}
	
	public MailBox getMailBoxByName(final String nameMailBox){
		return (MailBox) Executor.execute(new  Closure() {
			public Object execute() {
			return MailBoxSRV.getByName(nameMailBox);
			}
		});
	}
	
	public User getUserByUserName(final String userName){
		return (User) Executor.execute(new  Closure() {
			public Object execute() {
			return UserSRV.getByUserName(userName);
			}
		});
	}
	
	public PostOffice getPostOfficeByName(final String postOfficeName){
		return (PostOffice) Executor.execute(new  Closure() {
			public Object execute() {
			return PostOfficeSRV.getByName(postOfficeName);
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<MailBox> getMailBoxesByPostOffice(final long idPostOffice){
		return (Set<MailBox>) Executor.execute(new  Closure() {
			public Object execute() {
			return MailBoxSRV.getMailBoxesByPostOffice(idPostOffice);
			}
		});
	}
	
	@SuppressWarnings("unchecked")
	public Set<OutgoingMessage> getOutgoingMessagesByMailBox(final long idMailBox) {
		return (Set<OutgoingMessage>)Executor.execute(new Closure() {
			public Object execute() {
				return OutgoingMessageSRV.getOutgoingMessages(idMailBox);
			}
		});

	}
	
	@SuppressWarnings("unchecked")
	public Set<MailBox> getMailBoxesByUser(final long idUser){
		return (Set<MailBox>)Executor.execute(new Closure() {
			public Object execute() {
				return MailBoxSRV.getMailBoxesByUser(idUser);
			}
		});
	}
	
}
